/*
es5定义：Object.prototype.toString()会返回[object, [[class]]]字符串,其中[[class]]会返回es定义的对象类

为什么需要Object.prototype?

Object对象本身就有一个toString()方法，返回的是当前对象的字符串形式，原型上的toString()返回的才是我们真正需要的包含对象数据类型的字符串。

为什么需要call？

由于Object.prototype.toString()本身允许被修改，像Array、Boolean、Number的toString就被重写过，所以需要调用Object.prototype.toString.call(arg)来判断arg的类型，call将arg的上下文指向Object，所以arg执行了Object的toString方法。

至于call，就是改变对象的this指向，当一个对象想调用另一个对象的方法，可以通过call或者apply改变其this指向，将其this指向拥有此方法的对象，就可以调用该方法了。
call"调用一个对象的一个方法，以另一个对象替换当前对象.括号里面的原本的对象改为call()前面的对象、即用o代替call前面的东西，最终用o这个对象去执行call前面的方法 在toString方法使用时指定其this指向o
 */
function getType(o) {
    /*
     原型上的toString()返回的才是我们真正需要的包含对象数据类型的字符串 call将arg的上下文指向Object，所以arg执行了Object的toString方法(避免被重写，因为不同的数据类型都有其自身toString()方法)
     若参数不为 null 或 undefined，则将参数隐式转为对象，再作判断。对于原始类型，转为基本包装类型对象即装箱 如传入字符串，先装箱转为字符串类型对象，this指向这个字符串类型对象，这个字符串执行了Object原型上的toString方法，即要返回其类型
     */
    const res = Object.prototype.toString.call(o);
    let str = Array.from(res.split(" ")[1]);
    str.pop();
    return str.join('');
}

console.log(getType('1'));
console.log(Object.prototype.toString.call([]));
